package com.augurit.common.dao;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.augurit.common.base.dao.BaseDao;
import com.augurit.common.constant.OrgConstant;
import com.augurit.common.entity.OmOrg;
import com.augurit.common.system.convert.OmOrgConverter;
import com.augurit.common.system.web.org.form.OmOrgForm;
import com.augurit.common.util.lang.CollectionUtils;

/**
 * 机构部门DAO类
 */
@Repository
public class OmOrgDao extends BaseDao<OmOrg, Long> {

	@Autowired
	private OmOrgAdminDao omOrgAdminDao;
	
	/**
	 * 根据机构ID获取机构名称
	 * @param id 机构主键
	 * @return 机构名称
	 */
	public String getOrgName(Long id) {
		if(id != null){
			OmOrg entity = this.get(id);
			if(entity != null)
				return entity.getOrgName();
		}
		return null;
	}
	
	public OmOrgForm getForm(Long id){
		OmOrgForm form = null;
		
		if(id != null){
			OmOrg entity = this.get(id);
			if(entity != null){
				form = OmOrgConverter.convertToForm(entity);
			}
		}
		return form;
	}
	
	/**
	 * 保存工作组Form对象
	 * @param form 工作组Form对象
	 */
	public void save(OmOrgForm form){
		
		if(form != null){
			OmOrg entity = null;
			
			//准备VO对象
			boolean isNewEntity = false;
			if(form != null && form.getOrgId() != null){
				entity = this.get(form.getOrgId());
			}else{
				entity = new OmOrg();
				isNewEntity = true;
			}
			
			//属性值转换
			OmOrgConverter.convertToEntity(form, entity);
			
			//保存
			super.save(entity);
			
			//根据父菜单ID计算对象的层次、序列和所属应用ID等属性并保存
			updateAdditionalProperty(entity, isNewEntity);
			
			//回填ID属性值
			form.setOrgId(entity.getOrgId());
		}
	}
	
	/**
	 * 判断该用户是否为机构管理员
	 * @param userId 用户ID
	 * @param orgIds 机构ID或ID数组
	 * @return 是否为机构管理员.如果有权限返回true，没有权限则返回false
	 */
	public boolean isOrgAdmin(Long userId, Long... orgIds) {
		if (userId != null && orgIds != null){
			List<Long> canManageOrgIds = this.getCanManageOrgIds(userId);
			return CollectionUtils.containsAll(canManageOrgIds, orgIds);
		}else
			return false;
	}
	
	/**
	 * 获取授权机构下的所有的子机构，返回结果包括授权机构本身
	 * 即获取指定用户所有可授权管理的机构ID列表
	 * @param authUserId 授权用户ID
	 * @param return 获取授权机构下的所有的子机构
	 */
	public List<Long> getCanManageOrgIds(Long authUserId) {
		List<Long> result = null;
		
		if (authUserId != null) {
			// 获取授权机构id
			List<Long> authedOrgIds = omOrgAdminDao.getCanManageOrgIds(authUserId);

			// 通过机构序列查询所有授权机构的子机构
			result = this.getSelfAndChildOrgIds(authedOrgIds);
		}
		
		return result;
	}
	
	/**
	 * 获取机构下的所有的子机构，返回结果包括本身
	 * @param orgIds 机构ID列表
	 * @return
	 */
	public List<Long> getSelfAndChildOrgIds(List<Long> orgIds){
		if (orgIds != null && orgIds.size() > 0) {
			String hql = "select ps.orgId from OmOrg ps where 1!=1";
			
			for (Long orgId : orgIds){
				hql += " or ps.orgSeq like '%." + orgId + ".%'";
			}
			
			return this.find(hql);
		}else
			return null;
	}
	
	/**
	 * 根据父机构ID计算机构的层次、序列并保存
	 * @param entity
	 */
	public void updateAdditionalProperty(OmOrg entity, boolean isNewEntity){
		if(entity != null){
			
			//针对存在父机构的情况
			if(entity.getParentOrgId() != null){
				
				//获取父机构对象
				OmOrg parentOrg = this.get(entity.getParentOrgId());
				
				entity.setOrgLevel(parentOrg.getOrgLevel() == null ? 1 : parentOrg.getOrgLevel() + 1);
				entity.setOrgSeq(parentOrg.getOrgSeq() + entity.getOrgId() + ".");
				
				if(isNewEntity)
					this.updateOrgAfterAddChildren(parentOrg);
			}
			//针对无父机构的情况
			else{
				entity.setOrgLevel(1);
				entity.setOrgSeq("." + entity.getOrgId() + ".");
				entity.setIsLeaf(OrgConstant.ZERO);
				entity.setSubCount(0);
			}
			
			super.save(entity);
		}
	}
	
	/**
	 * 根据机构节点orgId获取所有的子机构，包括子机构的子机构，主要方法是通过模糊查询排列顺序编号orgSeq
	 * @param orgId 机构节点主键
	 * @return 节点对象的子机构主键集合
	 */
	public List<Long> getAllChildOrgIds(Long parentOrgId){
		if(parentOrgId != null)
			return partSelectByParentOrgId(parentOrgId, "orgId");
		else
			return null;
	}
	
	/**
	 * 根据机构节点orgId获取所有的子机构，包括子机构的子机构，主要方法是通过模糊查询排列顺序编号orgSeq
	 * @param parentOrgId 机构节点主键
	 * @return 节点对象的子机构主键集合
	 */
	public List<OmOrg> getAllChildOrgs(Long parentOrgId){
		if(parentOrgId != null)
			return partSelectByParentOrgId(parentOrgId, null);
		else
			return null;
	}
	
	/**
     * 返回要查询的结果
     * @param funcId
     * @param entityProperty
     * @return
     */
    private List partSelectByParentOrgId(Long parentOrgId, String entityProperty){
		String hql = "select " 
						+ (entityProperty != null && entityProperty.trim().length() > 0 ? "ps." + entityProperty : "ps") 
						+ " from OmOrg ps where ps.orgSeq like ? and ps.orgId != ?";
		List values = new ArrayList();
		values.add("%." + parentOrgId + ".%");
		values.add(parentOrgId);
		
		return this.find(hql,values);
	}

	/**
	 * 根据机构节点id获取直属子机构
	 * @param parentOrgId 机构节点主键
	 * @return 节点对象的子机构集合
	 */
	public List<OmOrgForm> getChildOrgs(Long parentOrgId){
		if(parentOrgId != null){
			
			String hql = "from OmOrg ps where ps.parentOrgId=? order by ps.sortNo asc";
			List values = new ArrayList();
			values.add(parentOrgId);
			List<OmOrg> list = this.find(hql, values);
			
			return OmOrgConverter.convertToFormList(list);
		}else
			return null;
	}
	
	/**
	 * 获取最上层机构列表
	 * @return
	 */
	public List<OmOrgForm> getTopOrgs(){
		String hql = "from OmOrg ps where ps.parentOrgId is null order by ps.sortNo asc";
		List<OmOrg> list = this.find(hql);
		return OmOrgConverter.convertToFormList(list);
	}

	/**
	 * 根据机构节点id将其父机构subCount+num
	 * @param id 机构节点主键
	 * @param num 要修改的数目大小
	 */
	public void modifyParentSubCount(Long orgId,int num){
		if(orgId != null){
			OmOrg entity = get(orgId);
			Long parentOrgId = entity.getParentOrgId(); 
			if(parentOrgId != null){
				OmOrg ParentEntity = get(parentOrgId);
				entity.setSubCount(ParentEntity.getSubCount()+num);
			}		
		}
	}
	
	/**
	 * 当指定机构节点移动后，修改其所有子机构的序列号
	 * @param id 机构节点主键
	 */
	public void updateOrgSeqAfterMoveOrg(OmOrg entity){
		if(entity != null ){
			List<OmOrg> list = getAllChildOrgs(entity.getOrgId());
			list.remove(entity);
			//得到新父节点序列
			String newParentOrgSeq = getOrgSeqAfterSaveOrg(entity);
			
			//更新本节点的序列
			entity.setOrgSeq(newParentOrgSeq);
			this.save(entity);
			
			//以新父节点序列为所有子
			this.updateOrgSeq(list,newParentOrgSeq);
		}
	}
	
	/**
	 * 更新List<OmOrg>的所有序列号，以参数newOrgSeq为父序列号
	 * @param id 机构节点主键
	 */
	public void updateOrgSeq(List<OmOrg> list,String newParentOrgSeq){
		if(list!= null && list.size() > 0){
			for (int i = 0; i < list.size(); i++) {
				OmOrg org =  list.get(i);
				org.setOrgSeq(newParentOrgSeq+org.getOrgId()+".");
				this.save(org);
			}
		}
	}
	/**
	 * 当指定机构添加了子对象后要对该机构的相关计算字段进行更新
	 * @param orgId 机构主键ID
	 */
	public void updateOrgAfterAddChildren(Long orgId){
		if(orgId != null){
			OmOrg org = this.get(orgId);
			updateOrgAfterAddChildren(org);
		}
	}
	
	/**
	 * 当指定模块添加了子对象后要对该机构的相关计算字段进行更新
	 * @param org 机构Entity对象
	 */
	public void updateOrgAfterAddChildren(OmOrg org){
		if(org != null){
			org.setSubCount(org.getSubCount() == null ? 0 : org.getSubCount() + 1);
			org.setIsLeaf(OrgConstant.ZERO);	//设置为非叶子节点
			this.save(org);
		}
	}
	
	/**
	 * 当指定机构删除了子对象后要对该机构的相关计算字段进行更新
	 * @param orgId 机构主键ID
	 */
	public void updateOrgAfterRemoveChildren(Long orgId){
		if(orgId != null){
			OmOrg org = this.get(orgId);
			updateOrgAfterRemoveChildren(org);
		}
	}
	
	/**
	 * 当指定模块删除了子模块或功能后，对该机构的相关计算字段进行更新
	 * @param org 机构Entity对象
	 */
	public void updateOrgAfterRemoveChildren(OmOrg org){
		if(org != null){
			int subCount = org.getSubCount() - 1;	//子节点数减1
			
			org.setSubCount(subCount);
			if(subCount == 0)
				org.setIsLeaf(OrgConstant.ONE);		//设置为叶子节点
			else
				org.setIsLeaf(OrgConstant.ZERO);		//设置为非叶子节点
				
			this.save(org);
		}
	}
	
	/**
	 * 当在数据库保存新的机构对象后，为它更新OrgSeq属性
	 * @param form 机构form对象
	 */
//	public String getOrgSeqAfterSaveOrg(OmOrgForm form){
//		if(form != null){
//			OmOrg entity = (OmOrg)DozerUtils.map(form,OmOrg.class);
//			return getOrgSeqAfterSaveOrg(entity);
//		}
//		return null;
//	}
	
	/**
	 * 当在数据库保存新的机构对象后，为它更新OrgSeq属性
	 * @param entity 机构对象
	 */
	public String getOrgSeqAfterSaveOrg(OmOrg entity){
		String orgSeq = null;
		if(entity != null){
			Long parentOrgId = entity.getParentOrgId();
			//如果有父节点，增加序列属性
			if(parentOrgId != null){
				OmOrg parentOrg = get(parentOrgId);
				orgSeq= parentOrg.getOrgSeq()+entity.getOrgId()+".";
			}
			//如果没有父节点,增加序列属性
			else orgSeq="."+entity.getOrgId()+".";
		}
		return orgSeq;
	}
	
	/**
	 * 获取最上层机构列表
	 * @param userId 管理用户主键
	 * */
	public List<OmOrgForm> getTopOrgs(Long userId) {
		if(userId != null){
			String hql = "select o from OmOrg o, OmOrgAdmin oa where o.orgId=oa.orgId and o.parentOrgId is null and oa.userId=?";
			List values = new ArrayList();
			values.add(userId);
			List<OmOrg> list = this.find(hql, values);
			return OmOrgConverter.convertToFormList(list);
		}
		return null;
	}
	
	/*public boolean hasOrgLikeKeyword(String keyword){
		if(keyword != null && keyword.trim().length()>0){
			String hql = "from OmOrg ps where ps.orgName like '"+keyword +"%'";
			List<OmOrg> list = this.find(hql);
			if(list != null && list.size()>0)
				return true;
			
		}
		return false;
	}*/
}
